import 'dart:math';

import 'package:animated_text_kit/animated_text_kit.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:chatgreat/bloc/creative_island_bloc.dart';
import 'package:chatgreat/helper/color.dart';
import 'package:chatgreat/helper/my_widget.dart';
import 'package:chatgreat/page/component/background_container.dart';
import 'package:chatgreat/page/component/sliver_component.dart';
import 'package:chatgreat/page/component/theme/custom_size.dart';
import 'package:chatgreat/page/component/theme/custom_theme.dart';
import 'package:chatgreat/repo/settings_repo.dart';
import 'package:clipboard/clipboard.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:go_router/go_router.dart';
import 'package:markdown_widget/config/all.dart';

import '../../../helper/AppUtil.dart';
import '../../../helper/helper.dart';
import '../../../repo/api/creative.dart';
import '../../../repo/api_server.dart';
import '../../chat/home.dart';
import '../../component/audio_player.dart';
import '../../component/chat/markdown.dart';
import '../../component/dialog.dart';
import '../../component/enhanced_textfield.dart';
import '../../login/model/tourist_login_model.dart';

class CreateGenerateScreen extends StatefulWidget {
  final SettingRepository setting;
  final CreativeIslandWork? creativeIslandWork;
  const CreateGenerateScreen(
      {super.key, required this.setting, this.creativeIslandWork});

  @override
  State<CreateGenerateScreen> createState() => _CreateGenerateScreenState();
}

enum GenerateStatus { display, generating, over }

class _CreateGenerateScreenState extends State<CreateGenerateScreen>
    with TickerProviderStateMixin {
  final TextEditingController _textController = TextEditingController();
  final ScrollController _scrollController = ScrollController();

  GenerateStatus _status = GenerateStatus.display;
  bool enableNotifier = true;
  bool isReady = false;
  bool isReadyRecord = false;

  // 音频播放器控制器
  final AudioPlayerController audioPlayerController =
      AudioPlayerController(useRemoteAPI: true);
  int? playingMessageId = 0;
  // 显示音频播放器的状态
  bool showAudioPlayer = false;
  // 是否显示音频播放器加载中
  bool audioLoadding = false;

  String text = '';
  late AnimationController animationController;
  final Duration animationDuration = const Duration(milliseconds: 60);
  int currentTextIndex = 0;

  @override
  void initState() {
    audioPlayerController.onPlayStopped = () {
      showAudioPlayer = false;
      audioLoadding = false;
      setState(() {});
    };
    audioPlayerController.onPlayAudioStarted = () {
      setState(() {
        showAudioPlayer = true;
      });
    };
    audioPlayerController.onPlayCompletion = () {
      playingMessageId = 0;
      showAudioPlayer = false;
      setState(() {});
    };

    audioPlayerController.onPlayAudioLoading = (loading) {
      setState(() {
        audioLoadding = loading;
      });
    };
    super.initState();
    animationController = AnimationController(
      duration: animationDuration,
      vsync: this,
    )..addListener(() {
      if (currentTextIndex < text.length) {
        setState(() {
          currentTextIndex++;
        });
      } else if (currentTextIndex >= text.length && isReadyRecord) {
        animationController.stop();
        isReady = isReadyRecord;
        setState(() {});
      }
    });

  }

  @override
  void dispose() {
    _textController.dispose();
    _scrollController.dispose();
    audioPlayerController.dispose();
    animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final customColors = Theme.of(context).extension<CustomColors>()!;
    // 十分恶心的机制
    return SizedBox(
      width: ScreenUtil().screenWidth,
      height:ScreenUtil().screenHeight,
      child: SingleChildScrollView(
        child: Container(
          width: ScreenUtil().screenWidth,
          height: ScreenUtil().screenHeight,
          decoration: const BoxDecoration(
            image: DecorationImage(
              image: AssetImage('images/bg1.png'),
              fit: BoxFit.fill,
            ),
          ),
          child: _buildIslandItems(customColors)
        ),
      ),
    );
  }

  /// 创作内容
  Widget _buildIslandItems(
    CustomColors customColors,
  ) {
    return SliverCreateComponent(
      title: Text(
        widget.creativeIslandWork?.name ?? "创作",
        style: const TextStyle(
          fontSize: CustomSize.appBarTitleSize,
          color: Colors.white,
        ),
      ),
      leading: IconButton(
        icon: Icon(
          Icons.arrow_back,
          color: customColors.weakLinkColor,
        ),
        onPressed: () {
          if (context.canPop()) {
            if (animationController.isAnimating) {
              animationController.stop();
            }
            audioPlayerController.stop();
            context.pop();
          }
        },
      ),
      child: BlocBuilder<CreativeIslandBloc, CreativeIslandState>(
        buildWhen: (previous, current) =>
            current is CreativeIslandItemsWorkLoaded,
        builder: (context, state) {

          RegExp _blacklistedPattern = RegExp("[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]");
          return Column(
            children: [
              Container(
                padding: const EdgeInsets.only(left: 15, right: 12, bottom: 10),
                alignment: Alignment.centerLeft,
                child: MyTextWeight(
                    widget.creativeIslandWork?.title ?? '创作报告原创内容',
                    15,
                    Colors.white.withOpacity(0.6),
                    FontWeight.normal),
              ),
              Container(
                margin: const EdgeInsets.only(left: 12, right: 12),
                padding: const EdgeInsets.only(left: 16, right: 10),
                height: 160,
                decoration: BoxDecoration(
                  color: stringToColor('FF21222F'),
                  borderRadius: BorderRadius.circular(13.0),
                ),
                child: EnhancedTextField(
                  onFocusChange: (hasFocus) {},
                  controller: _textController,
                  enabled: enableNotifier,
                  customColors: customColors,
                  maxLines: 5,
                  inputFormatters: [
                    LengthLimitingTextInputFormatter(50),
                    FilteringTextInputFormatter(_blacklistedPattern, allow: false)
                  ],
                  hintText: widget.creativeIslandWork?.remark ??
                      '这里输入你要生成报告的主题，例如：本周工作总结报告...',
                  maxLength: 50,
                  showCounter: true,
                  keyboardType: TextInputType.text,
                  hintColor: Colors.white.withOpacity(0.32),
                  hintTextSize: 15,
                ),
              ),
              Visibility(
                visible: _status != GenerateStatus.display,
                child: Container(
                  padding: const EdgeInsets.only(
                      left: 15, right: 15, bottom: 10, top: 20),
                  alignment: Alignment.centerLeft,
                  child: MyTextWeight('生成内容', 15, Colors.white.withOpacity(0.6),
                      FontWeight.normal),
                ),
              ),
              _generateContent(),
              Container(
                margin: const EdgeInsets.only(left: 16, right: 16, bottom: 36),
                width: double.infinity,
                decoration: const BoxDecoration(
                  image: DecorationImage(
                    image: AssetImage('images/guide_button.png'),
                    fit: BoxFit.fill,
                  ),
                ),
                child: TextButton(
                  child:
                      MyTextWeight('生成内容', 16, Colors.white, FontWeight.normal),
                  onPressed: () async {
                    if (!enableNotifier) {
                      return;
                    }

                    FocusScope.of(context).requestFocus(FocusNode());
                    TouristLoginModel touristLoginModel = await APIServer().getUserInfo();
                    if (touristLoginModel.isVip == 0 && touristLoginModel.freeCount == 0) {
                      showVipGlobalDialog(context);
                      return;
                    }

                    // 停止正在播放的语音
                    if (audioPlayerController.player.state == PlayerState.playing) {
                      playingMessageId = 0;
                      audioPlayerController.stop();
                    }
                    setState(() {
                      _status = GenerateStatus.generating;
                    });

                    currentTextIndex = 0;
                    context.read<CreativeIslandBloc>().add(
                        CreateGenerateContentLoadEvent(
                            widget.creativeIslandWork?.id ?? 1,
                            content: _textController.text));
                  },
                ),
              )
            ],
          );
        },
      ),
    );
  }

  Widget _generateContent() {
    final customColors = Theme.of(context).extension<CustomColors>()!;
    return Expanded(
        child: _status != GenerateStatus.display
            ? BlocConsumer<CreativeIslandBloc, CreativeIslandState>(
                listener: (context, state) {
                  if (state is CreateGenerateContentIsReadyLoaded) {
                    setState(() {
                      if (!animationController.isAnimating) {
                        isReady = state.isReady;
                      }
                      isReadyRecord = state.isReady;
                    });
                  }
                  if (state is CreateGenerateContentWorkLoaded) {
                    // 内容窗口滚动到底部
                    if (!state.processing && _scrollController.hasClients) {
                      _scrollController.animateTo(
                        0,
                        duration: const Duration(milliseconds: 500),
                        curve: Curves.easeOut,
                      );
                    }

                    if (state.processing && enableNotifier) {
                      animationController.repeat();
                      // 聊天回复中时，禁止输入框编辑
                      setState(() {
                        enableNotifier = false;
                        _status = GenerateStatus.generating;
                      });
                    } else if (!state.processing && !enableNotifier) {
                      // 聊天回复完成时，取消输入框的禁止编辑状态
                      setState(() {
                        enableNotifier = true;
                        _status = GenerateStatus.over;
                      });
                    }
                  }
                },
                buildWhen: (previous, current) =>
                    current is CreateGenerateContentWorkLoaded ||
                    current is CreateGenerateContentIsReadyLoaded,
                builder: (context, state) {
                  if (state is CreateGenerateContentWorkLoaded) {
                    return buildContentPreviewArea(state);
                  }
                  return Align(
                    alignment: Alignment.topLeft,
                    child: Container(
                        width: 20,
                        height: 20,
                        margin: const EdgeInsets.only(left: 16, top: 12),
                        child: const CircularProgressIndicator(
                            color: Colors.white, strokeWidth: 2)),
                  );
                },
              )
            : const Text(''));
  }

  Widget buildContentPreviewArea(CreateGenerateContentWorkLoaded state) {
    return Column(children: [
      Flexible(
        child: Container(
          width: double.infinity,
          margin: const EdgeInsets.only(left: 12, right: 12, bottom: 10),
          padding:
              const EdgeInsets.only(left: 18, top: 16, bottom: 16, right: 12),
          decoration: BoxDecoration(
            color: stringToColor('FF07060A'),
            borderRadius: BorderRadius.circular(13.0),
            border: Border.all(
              color: stringToColor('FF5F6175'), // 边框颜色
              width: 0.5, // 边框宽度
            ),
          ),
          child: CustomScrollView(
            reverse: true,
            shrinkWrap: true,
            controller: _scrollController,
            slivers: [
              SliverToBoxAdapter(
                child: ListView.builder(
                  itemCount: state.message.text.isNotEmpty ? 1 : 0,
                  shrinkWrap: true,
                  reverse: true,
                  physics: const BouncingScrollPhysics(),
                  cacheExtent: ScreenUtil().screenHeight * 8,
                  itemBuilder: (context, index) {
                    return Column(
                      children: [
                        Row(
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            // 消息主体部分
                            Expanded(
                              child: Container(
                                child: _buildMessageBox(
                                  context,
                                  state,
                                  index,
                                ),
                              ),
                            ),
                          ],
                        ),
                      ],
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      ),
      Visibility(
        visible: isReady,
        child: Padding(
          padding: const EdgeInsets.only(left: 12, right: 12, bottom: 32),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              //播放
              GestureDetector(
                onTap: () {
                  if (audioLoadding) {
                    return;
                  }
                  if (showAudioPlayer) {
                    playingMessageId = 0;
                    audioPlayerController.stop();
                  } else {
                    playingMessageId = state.message.id;
                    audioPlayerController
                        .playAudioWithMessageId(playingMessageId ?? 0);
                  }
                },
                child: Row(
                  children: [
                    Container(
                      // width: 65,
                      height: 32,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(8),
                        color: Colors.white.withOpacity(0.12),
                      ),
                      padding: const EdgeInsets.only(
                          left: 9, right: 9, top: 7, bottom: 7),
                      child: Row(
                        children: [
                          imgWidget(
                              17,
                              17,
                              (showAudioPlayer &&
                                      state.message.id == playingMessageId)
                                  ? 'play'
                                  : 'stop'),
                          const SizedBox(
                            width: 8.5,
                          ),
                          // gif
                          if (audioPlayerController != null &&
                              state.message.id == playingMessageId)
                            EnhancedAudioPlayer(
                              controller: audioPlayerController!,
                              loading: audioLoadding,
                            ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
              //更多
              Container(
                height: 32,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(8),
                  color: Colors.white.withOpacity(0.12),
                ),
                child: Row(
                  children: [
                    GestureDetector(
                      onTap: () {
                        var replacedString = state.message.text.replaceAll('\\n', '\\\n');
                        replacedString = replacedString.replaceAll('\\', '');

                        FlutterClipboard.copy(replacedString).then((value) {
                          showSuccessMessage('已复制到剪贴板');
                        });
                      },
                      child: Container(
                          padding: const EdgeInsets.only(right: 2),
                          width: 45,
                          height: 30,
                          child: Center(
                            child: imgWidget(17, 17, 'copy'),
                          )),
                    ),
                    Container(
                      margin: const EdgeInsets.only(top: 6.5, bottom: 6.5),
                      color: const Color(0xFF4B4A4D),
                      width: 1,
                    ),
                    GestureDetector(
                      onTap: () {
                        EasyLoading.show(status: '请稍等...');
                        APIServer()
                            .clickLike(state.message.id ?? 0,
                                state.message.like == 0 ? 1 : 0)
                            .then((value) {
                          EasyLoading.dismiss();

                          state.message.like = state.message.like == 0 ? 1 : 0;

                          setState(() {});
                        }).onError((error, stackTrace) {
                          EasyLoading.dismiss();
                          showErrorMessage(resolveError(context, error!));
                        });
                      },
                      child: SizedBox(
                          width: 40,
                          height: 30,
                          child: Center(child: imgWidget(17, 17, state.message.like == 0 ? 'zan' : 'yizan'))),
                    ),
                    Container(
                      margin: const EdgeInsets.only(top: 6.5, bottom: 6.5),
                      color: const Color(0xFF4B4A4D),
                      width: 1,
                    ),
                    GestureDetector(
                      onTap: () {
                        EasyLoading.show(status: '请稍等...');
                        APIServer()
                            .clickCollect(state.message.id ?? 0,
                                state.message.collection == 0 ? 1 : 0)
                            .then((value) {
                          EasyLoading.dismiss();

                          state.message.collection =
                              state.message.collection == 0 ? 1 : 0;

                          setState(() {});
                        }).onError((error, stackTrace) {
                          EasyLoading.dismiss();
                          showErrorMessage(resolveError(context, error!));
                        });
                      },
                      child: Container(
                          padding: const EdgeInsets.only(left: 2),
                          width: 45,
                          height: 30,
                          child: Center(
                            child: imgWidget(
                                17,
                                17,
                                state.message.collection == 0
                                    ? 'collection0'
                                    : 'collection1'),
                          )),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    ]);
  }

  /// 构建消息框
  Widget _buildMessageBox(
    BuildContext context,
    CreateGenerateContentWorkLoaded state,
    int index,
  ) {
    // 普通消息
    return ConstrainedBox(
      constraints: BoxConstraints(maxWidth: _chatBoxMaxWidth(context)),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          ConstrainedBox(
            constraints: BoxConstraints(
              maxWidth: _chatBoxMaxWidth(context) - 29 * 2,
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Wrap(
                  crossAxisAlignment: WrapCrossAlignment.end,
                  children: [
                    // 消息主体
                    GestureDetector(
                      onTap: () {
                        // 单击隐藏键盘
                        FocusScope.of(context).requestFocus(FocusNode());
                      },
                      child: Stack(
                        children: [
                          Builder(
                            builder: (context) {
                              var text =
                                  state.message.text.replaceAll('\\n', '\n');
                              this.text = text;

                              return Column(
                                mainAxisSize: MainAxisSize.min,
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  AnimatedBuilder(
                                      animation: animationController,
                                      builder: (context, animateState) {
                                        var showText = text.substring(0, currentTextIndex);
                                        if (!isReady && showText != '') {
                                          showText += ' ▌';
                                        }
                                        return Markdown(
                                          textStyle: const TextStyle(
                                              fontSize: 15,
                                              color: Colors.white),
                                          data: showText.trim(),
                                        );
                                      })

                                  // AnimatedTextKit(
                                  //     totalRepeatCount: 1,
                                  //     animatedTexts: [
                                  //       TypewriterAnimatedText(text.trim(),
                                  //           speed: const Duration(
                                  //               milliseconds: 50),
                                  //           textStyle: const TextStyle(
                                  //             color: Colors.white,
                                  //             fontSize: 17,
                                  //           )),
                                  //     ],
                                  //     onFinished: () {
                                  //
                                  //     }),
                                ],
                              );
                            },
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  /// 获取聊天框的最大宽度
  double _chatBoxMaxWidth(BuildContext context) {
    var screenWidth = ScreenUtil().screenWidth;
    if (screenWidth >= CustomSize.maxWindowSize) {
      return CustomSize.maxWindowSize;
    }

    return screenWidth;
  }
}

class MyLengthLimitingTextInputFormatter extends TextInputFormatter{

  final int? maxLength;

  MyLengthLimitingTextInputFormatter(this.maxLength) : assert(maxLength == null || maxLength == -1 || maxLength > 0);

  @visibleForTesting
  static TextEditingValue truncate(TextEditingValue value, int maxLength) {
    final CharacterRange iterator = CharacterRange(value.text);
    if (value.text.length > maxLength) {
      iterator.expandNext(maxLength);
    }
    final String truncated = iterator.current;

    return TextEditingValue(
      text: truncated,
      selection: value.selection.copyWith(
        baseOffset: min(value.selection.start, truncated.length),
        extentOffset: min(value.selection.end, truncated.length),
      ),
      composing: !value.composing.isCollapsed && truncated.length > value.composing.start
          ? TextRange(
        start: value.composing.start,
        end: min(value.composing.end, truncated.length),
      )
          : TextRange.empty,
    );
  }

  //oldValue就是显示在输入框上的旧值，newValue就是显示在输入框上的旧值加你新输入的字符串
  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue,
      TextEditingValue newValue,
      ) {
    final int? maxLength = this.maxLength;

    //加上你新输入的字符串都没大于限制的最大值就直接在输入框显示新字符串
    if (maxLength == null ||
        maxLength == -1 ||
        newValue.text.characters.length <= maxLength) {
      return newValue;
    }

    assert(maxLength > 0);

    //已经达到最大值且新输入的字符串不是正在输入的状态
    //（真正输入存活状态：拼音拼出的字还没选中（下面会有下划线）或者手写的字还没在输入法选中（下面会有下划线）；
    //存活状态就是反过来，选中了或者输入英文的时候就是打出的每个字母都直接到输入框，下面也不会有下划线） ，直接返回旧的值
    if (oldValue.text.characters.length == maxLength && !newValue.composing.isValid) {
      return oldValue;
    }
    //已经达到最大值且新输入的字符串是正在输入的状态,显示旧值+你新输入的值=newValue,
    //就是这句解决了拼音会被吞的问题
    if (oldValue.text.characters.length == maxLength && newValue.composing.isValid){
      return newValue;
    }

    // Enforced to return a truncated value.
    return truncate(newValue, maxLength);
  }

}

